home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 19 / CD_ASCQ_19_010295.iso / dos / prg / pas / swag / oop.swg / 0032_OOP Stack Object.pas < prev    next >
Pascal/Delphi Source File  |  1994-01-27  |  5KB  |  230 lines

  1. {
  2. > If you want, I can post a few good and simple examples of OOP
  3. > concepts to get you started.
  4.  
  5. {
  6.   -- A simple stack object with the nice flexibility that only OOP
  7.      can provide.
  8.  
  9.                        Data structures
  10.  
  11.      StackItem: node for a doubly linked list containing an untyped pointer
  12.                 to hold data. It is the responsibility of descendant types
  13.                 to type this pointer. (override push and pop)
  14.  
  15.      StackTop    :pointer to available stack item
  16.      StackBottom :pointer to the bottom (end/root) of the stack
  17.      StackHt     :number of items on stack
  18.      StackST     :status variable
  19.  
  20.                              Methods
  21.  
  22.      Init - initializes the stack object, StackHt = 0, all pointers = nil
  23.             *** YOU MUST CALL THIS BEFORE ACCESSING STACK ***
  24.  
  25.      done - destructor deallocates the stack by doing successive pops until
  26.             the stack is empty.
  27.             *** YOU MUST OVERRIDE THIS METHOD WHEN YOU OVERRIDE ***
  28.             *** PUSH AND POP. ITEMS POPPED ARE NOT DEALLOCATED  ***
  29.  
  30.      Push - Pushes an item onto the stack by:
  31.             1) Allocating a new StackItem (if StackHt>0)
  32.             2) Assigning pointer dta to data field
  33.             3) Incrementing StackHt
  34.  
  35.      Pop  - Pops by reversing push method:
  36.             1) Recovering dta pointer from data field
  37.             2) Deallocating "top" StackItem (if StackHt>1)
  38.             3) Decrementing StackHt
  39.  
  40.  Most decendant types will override push and pop to type the data field, and
  41.  call STACK.push or STACK.pop to do the "basic" operations.
  42.  
  43.  IsError - shows if an error condition exists
  44.  
  45.  MemoryOK - internally used function to check available heap.
  46. }
  47.  
  48. Unit OSTACK;
  49.  
  50. INTERFACE
  51.  
  52. CONST
  53.    MAX_STACK   = 100;
  54.    MIN_MEMORY  = 4096;
  55.  
  56.    StatusOK    = 0;
  57.    StatusOFlow = 1;
  58.    StatusEmpty = 2;
  59.    StatHeapErr = 3;
  60.  
  61. TYPE
  62.    ItemPtr = ^StackItem;
  63.    StackItem = RECORD
  64.       data       :pointer;
  65.       prev, next :ItemPtr;
  66.    END; { StackItem }
  67.  
  68.    STACK = OBJECT
  69.       StackTop, StackBottom :ItemPtr;
  70.       StackST               :integer;
  71.       StackHt               :byte;
  72.  
  73.       constructor init;
  74.       destructor  done; virtual;
  75.       procedure   push(var d); virtual;
  76.       procedure   pop(var d); virtual;
  77.       function    IsError:boolean;
  78.    private
  79.       function    MemoryOK:boolean;
  80.    END; { STACK }
  81.  
  82. IMPLEMENTATION
  83.  
  84. constructor STACK.init;
  85.    BEGIN
  86.       New(StackBottom);
  87.       StackTop := StackBottom;
  88.       StackBottom^.prev := NIL;
  89.       StackBottom^.next := NIL;
  90.       StackBottom^.data := NIL;
  91.       StackHt := 0; StackST := StatusOK;
  92.    END;
  93.  
  94. destructor  STACK.done;
  95.    VAR  val :pointer;
  96.    BEGIN
  97.       if StackHt>0 then
  98.          repeat
  99.             pop(val);
  100.          until val = nil;
  101.       Dispose(StackBottom);
  102.    END;
  103.  
  104. procedure   STACK.push(var d);
  105.    VAR TemPtr :ItemPtr;
  106.        dta    :pointer ABSOLUTE d;
  107.    BEGIN
  108.       if not MemoryOK then EXIT;
  109.  
  110.       if (StackHt>=MAX_STACK) then
  111.       begin
  112.          StackST := StatusOFlow;
  113.          EXIT;
  114.       end;
  115.  
  116.       If StackHt>0 then
  117.       BEGIN
  118.          New(StackTop^.next);
  119.          TemPtr := StackTop;
  120.          StackTop := TemPtr^.next;
  121.          StackTop^.prev := TemPtr;
  122.          StackTop^.next := NIL;
  123.       END;
  124.  
  125.       StackTop^.data := dta;
  126.       Inc(StackHt);
  127.    END;
  128.  
  129. procedure   STACK.pop(var d);
  130.    VAR dta :pointer ABSOLUTE d;
  131.    BEGIN
  132.       if StackHt>1 then
  133.       BEGIN
  134.          dta := StackTop^.data;
  135.          StackTop := StackTop^.prev;
  136.          Dispose(StackTop^.next);
  137.          StackTop^.next := NIL;
  138.          Dec(StackHt);
  139.          if StackST = StatusOFlow then StackST := StatusOK;
  140.       END
  141.       ELSE
  142.       BEGIN
  143.          if StackHt = 1 then
  144.          BEGIN
  145.             dta := StackBottom^.data;
  146.             StackBottom^.data := nil;
  147.             Dec(StackHt);
  148.          END
  149.          ELSE
  150.          begin
  151.             dta := StackBottom^.data;
  152.             StackST := StatusEmpty;
  153.          end;
  154.       END;
  155.    END;
  156.  
  157. function    STACK.IsError:boolean;
  158. begin
  159.    if StackST = StatusOK then
  160.       IsError := FALSE
  161.    else
  162.       IsError := TRUE;
  163. end;
  164.  
  165. function    STACK.MemoryOK:boolean;
  166. begin
  167.    if MaxAvail<MIN_MEMORY then
  168.       MemoryOK := FALSE
  169.    else
  170.       MemoryOK := TRUE;
  171.    StackST := StatHeapErr;
  172. end;
  173.  
  174. END. { unit OSTACK }
  175.  
  176.  
  177. { Here's an example of how easy it is to extend the STACK object
  178.   using iheritance and virtual methods. }
  179.  
  180.  
  181. TYPE
  182.    RegisterStack = OBJECT(STACK)
  183.       destructor  Done; virtual;
  184.  
  185.       procedure   push(var d); virtual;
  186.       procedure   pop(var d); virtual;
  187.    end;
  188.  
  189. destructor  Done;
  190. var
  191.    tmp :OpRec;
  192. begin
  193.    if StackHt>0 then
  194.       repeat
  195.          pop(tmp);
  196.       until tmp = NOREG;
  197. end;
  198.  
  199. procedure  RegisterStack.push(var d);
  200. var
  201.    tmp :pOpRec;
  202.    dta :OpRec ABSOLUTE d;
  203. begin
  204.    New(tmp);
  205.    tmp^ := dta;
  206.    inherited push(tmp);
  207. end;
  208.  
  209. procedure  RegisterStack.pop(var d);
  210. var
  211.    tmp :pOpRec;
  212.    dta :OpRec ABSOLUTE d;
  213. begin
  214.    inherited pop(tmp);
  215.    if StackST = StatusEmpty then
  216.    begin
  217.       dta := NOREG;
  218.       EXIT;
  219.    end
  220.    else
  221.       if tmp<>nil then
  222.       begin
  223.          dta := tmp^;
  224.          Dispose(tmp);
  225.       end
  226.       else
  227.          dta := NOREG;
  228. end;
  229.  
  230.